<script setup>
import {computed, ref} from 'vue'
import VueDraggable from 'vuedraggable'

const drag = ref(false)

const emits = defineEmits(['update:modelValue', 'update'])
const props = defineProps({
  modelValue: {
    type: Array,
    default: []
  },
  childElStyle: {
    type: Object,
    default: {}
  },
  itemKey: {
    type: String,
    required: true
  },
  notHeader: {
    type: Boolean,
    default: false
  }
})

/**
 * https://blog.csdn.net/m0_67393413/article/details/123305144
 * 解决嵌套v-model问题（利用「计算属性」这个中间商）
 * @type {WritableComputedRef<any[]>}
 */
const middleman = computed({
  get() {
    return props.modelValue
  },
  set(val) {
    emits('update:modelValue', val)
  }
})

const dragOptions = computed(() => {
  return {
    animation: 250,
    group: "description",
    disabled: false,
    ghostClass: "ghost"
  }
})

const componentData = computed(() => {
  return {
    tag: 'ul',
    type: 'transition-group',
    name: !drag.value ? 'flip-list' : null
  }
})

const handleStart = () => {
  drag.value = true
}

const handleEnd = () => {
  drag.value = false
}

const handleUpdate = e => {
  emits('update', e.oldDraggableIndex, e.newDraggableIndex)

  // console.log(e)
  // const obj = {
  //   moveTarget: e.item._underlying_vm_.id,
  //   toIndex: e.newDraggableIndex
  // }
  // emits('update', obj)
}
</script>

<template>
  <VueDraggable
      class="list-group"
      v-model="middleman"
      v-bind="dragOptions"
      :component-data="componentData"
      @start="handleStart"
      @end="handleEnd"
      @update="handleUpdate"
      :item-key="props.itemKey"
  >
    <!--当前CSS布局下，使用footer插槽会有BUG-->
    <template #header>
      <li v-if="!props.notHeader">
        <slot name="header"></slot>
      </li>
    </template>
    <template #item="{element}">
      <li class="list-group-item" :style="childElStyle">
        <slot name="item" :element="element"></slot>
      </li>
    </template>
  </VueDraggable>
</template>

<style scoped>
.flip-list-move {
  transition: transform 0.5s;
}

.no-move {
  transition: transform 0s;
}

.ghost {
  opacity: 0.1;
  background: black;
}

.list-group {
  list-style-type: none;
  display: flex;
  flex-wrap: wrap;
}

.list-group-item {
  cursor: pointer;
}
</style>